home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 The Geometry Center; University of Minnesota
- 1300 South Second Street; Minneapolis, MN 55454, USA;
-
- This file is part of geomview/OOGL. geomview/OOGL is free software;
- you can redistribute it and/or modify it only under the terms given in
- the file COPYING, which you should have received along with this file.
- This and other related software may be obtained via anonymous ftp from
- geom.umn.edu; email: software@geom.umn.edu. */
-
- /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
-
- #include <gl/gl.h>
- #include <mgP.h>
- #include <mgglP.h>
-
- #undef P
- /* ^^^ evil kludge XXX to get the P variables here to not get confused
- * with the P prototype macro. -nils */
- #define HAS_N 1
- #define HAS_C 2
- #define HAS_SMOOTH 4
-
- int
- mggl_mesh( wrap, nu, nv, P, N, C)
- int wrap;
- int nu, nv;
- HPoint3 *P;
- Point3 *N;
- ColorA *C;
- {
- return mgsubmesh( wrap, nu, nv, 0, nu-1, 0, nv-1, P, N, C);
- }
-
- mgsubmesh( wrap, nu, nv, umin, umax, vmin, vmax, meshP, meshN, meshC)
- int wrap;
- int umin, umax, vmin, vmax;
- HPoint3 *meshP;
- Point3 *meshN;
- ColorA *meshC;
- {
- register int u, v;
- int ucnt, vcnt;
- register HPoint3 *P;
- register Point3 *N;
- register ColorA *C;
- register int prev;
- int du;
- int douwrap;
- HPoint3 tp;
- Point3 tn;
- int i;
- int has;
- Appearance *ap;
-
-
- if(nu <= 0 || nv <= 0)
- return 0;
-
- ap = &_mgc->astk->ap;
- if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
- meshC = 0;
-
- has = 0;
- if(meshN)
- has = HAS_N;
- if(meshC)
- has |= HAS_C;
- if(ap->shading == APF_SMOOTH)
- has |= HAS_SMOOTH;
-
-
- if( ap->flag & APF_FACEDRAW ) { /* Draw faces */
-
- /* We triangulate strips of (v,u) mesh points:
- * (v,u) (v,u+1) (v,u+2) ...
- * (v+1,u) (v+1,u+1) (v+1,u+2) ...
- * using the vertex sequence
- * (v,u) , (v+1,u), (v,u+1), (v+1,u+1), (v,u+2), ...
- * This covers the territory from v to v+1; then repeat for other v's.
- * If we hit the 256-vertex triangle-mesh limit, the strip is spliced
- * by redrawing the latest (v,u+i),(v+1,u+i) pair of vertices.
- */
-
- register void (*n3func)() = _mgglc->n3f;
- register void (*d4func)() = _mgglc->d4f;
-
- lmcolor(_mgglc->lmcolor);
- if(!(has & HAS_C))
- (*_mgglc->d4f)(&ap->mat->diffuse);
-
- v = vmax - vmin + 1;
- du = umin + vmin * nu;
-
- if(wrap & MM_VWRAP) {
- /* V-wrapping: cur = mesh[vmin,u], prev = mesh[vmax,u] */
- prev = nu * (v - 1);
- } else {
- /* Not V-wrapping: cur = mesh[vmin+1,u], prev = mesh[vmin,u] */
- du += nu;
- prev = -nu;
- v--; /* One less V-row, too */
- }
-
- do { /* Loop over V */
- P = meshP + du;
- N = meshN + du;
- C = meshC + du;
- ucnt = umax - umin + 1;
- if(_mgglc->turbo) {
- mgglpolymeshrow(wrap, has, prev, ucnt, P,
- has&HAS_N ? N : NULL,
- has&HAS_C ? C : NULL);
- } else {
- bgntmesh();
- douwrap = (wrap & MM_UWRAP);
- do {
- /* Loop over U */
- u = ucnt < 126 ? ucnt : 126; /* 256-vertex tmesh limit */
- ucnt -= u;
-
- switch( has ) {
-
- case 0:
- case HAS_SMOOTH:
- do {
- v4f((float *)P+prev);
- v4f((float *)P);
- P++;
- } while(--u);
- break;
-
- case HAS_C:
- do {
- (*d4func)(C+prev); v4f((float *)(P+prev));
- v4f((float *)P);
- C++; P++;
- } while(--u);
- break;
-
- case HAS_C|HAS_SMOOTH:
- do {
- (*d4func)(C+prev); v4f((float *)(P+prev));
- (*d4func)(C); v4f((float *)P);
- C++; P++;
- } while(--u);
- break;
-
- case HAS_N:
- do {
- (*n3func)(N+prev,P); v4f((float *)(P+prev));
- v4f((float *)P);
- N++; P++;
- } while(--u);
- break;
-
- case HAS_N|HAS_SMOOTH:
- do {
- (*n3func)(N+prev,P); v4f((float *)(P+prev));
- (*n3func)(N,P); v4f((float *)P);
- N++; P++;
- } while(--u);
- break;
-
- case HAS_C|HAS_N:
- do {
- (*d4func)(C+prev); (*n3func)(N+prev,P); v4f((float *)(P+prev));
- v4f((float *)P);
- C++; N++; P++;
- } while(--u);
- break;
-
- case HAS_C|HAS_N|HAS_SMOOTH:
- do {
- (*d4func)(C+prev); (*n3func)(N+prev,P); v4f((float *)(P+prev));
- (*d4func)(C); (*n3func)(N,P); v4f((float *)P);
- C++; N++; P++;
- } while(--u);
- break;
- }
-
- if(ucnt == 0) {
- if(douwrap) {
- douwrap = 0; /* Loop again on first vertex */
- ucnt = 1;
- P = meshP + du;
- N = meshN + du;
- C = meshC + du;
- }
- } else {
- endtmesh(); /* Hit tmesh limit, splice */
- bgntmesh();
- C--; N--; P--; /* Redraw last vertex */
- }
- } while(ucnt);
-
- endtmesh();
- }
- prev = -nu;
- du += nu;
- } while(--v > 0);
- }
-
- if(ap->flag & (APF_EDGEDRAW|APF_NORMALDRAW)) {
- lmcolor(LMC_COLOR);
- if(_mgglc->znudge) mggl_closer();
- if(ap->flag & APF_EDGEDRAW) { /* Draw edges */
- c3f((float *)&ap->mat->edgecolor);
-
- du = umin + vmin * nu;
- ucnt = umax - umin + 1;
- vcnt = vmax - vmin + 1;
- v = vcnt;
- do {
- if(wrap & MM_UWRAP)
- bgnclosedline();
- else
- bgnline();
- u = ucnt;
- P = meshP + du;
- do {
- v4f((float *)P);
- P++;
- } while(--u > 0);
- if(wrap & MM_UWRAP)
- endclosedline();
- else
- endline();
- du += nu;
- } while(--v > 0);
-
- du = umin + vmin * nu;
- u = ucnt;
- do {
- v = vcnt;
- if(wrap & MM_VWRAP)
- bgnclosedline();
- else
- bgnline();
- P = meshP + du;
- do {
- v4f((float *)P);
- P += nu;
- } while(--v > 0);
- if(wrap & MM_VWRAP)
- endclosedline();
- else
- endline();
- du++;
- } while(--u > 0);
- }
-
- if(ap->flag & APF_NORMALDRAW && meshN != NULL) {
- c3f((float *)&ap->mat->normalcolor);
-
- for (i = nu*nv, P=meshP, N=meshN; --i >= 0; P++, N++) {
- mggl_drawnormal(P, N);
- }
- }
- if(_mgglc->znudge) mggl_farther();
- }
- return 1;
- }
-
- /*
- * Draw a single row of a mesh, using polygons.
- * This routine is needed to work around a bug in Turbo PI graphics:
- * lighted tmesh primitives are not shaded properly.
- * Polygons are OK though, so on Turbo machines we use them.
- */
- mgglpolymeshrow(wrap, has, off, count, P, N, C)
- int wrap;
- int has;
- register int off;
- register HPoint3 *P;
- register Point3 *N;
- register ColorA *C;
- {
- int k;
- void (*n3func)() = _mgglc->n3f;
- void (*d4func)() = _mgglc->d4f;
-
- if(wrap & MM_UWRAP) {
- k = count-1;
- bgnpolygon();
- if(C) (*d4func)(C+off+k);
- if(N) (*n3func)(N+off+k,P);
- v4f((float *)(P+off+k));
- if(has&HAS_SMOOTH) {
- if(C) (*d4func)(C+k);
- if(N) (*n3func)(N+k,P);
- }
- v4f((float *)(P+k));
- if(has&HAS_SMOOTH) {
- if(C) (*d4func)(C);
- if(N) (*n3func)(N,P);
- }
- v4f((float *)P);
- if(has&HAS_SMOOTH) {
- if(C) (*d4func)(C+off);
- if(N) (*n3func)(N+off,P);
- }
- v4f((float *)(P+off));
- endpolygon();
- }
- k = count;
- do {
- bgnpolygon();
- if(C) (*d4func)(C+off);
- if(N) (*n3func)(N+off,P);
- v4f((float *)(P+off));
- if(has&HAS_SMOOTH) {
- if(C) (*d4func)(C+off);
- if(N) (*n3func)(N+off,P);
- v4f((float *)(P+off));
- if(C) (*d4func)(C++);
- if(N) (*n3func)(N++,P);
- v4f((float *)P++);
- if(C) (*d4func)(C);
- if(N) (*n3func)(N,P);
- v4f((float *)P);
- if(C) (*d4func)(C+off);
- if(N) (*n3func)(N+off,P);
- v4f((float *)(P+off));
- } else {
- v4f((float *)(P+off));
- if(C) C++;
- if(N) N++;
- v4f((float *)(P++));
- v4f((float *)P);
- v4f((float *)(P+off));
- }
- endpolygon();
- } while(--k > 1);
- }
-